package com.yootk.test.hc;

import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * HTTPS协议访问
 */
public class HttpClientHttpsDemo {

    public static void main(String[] args) throws Exception {
        // 1、当前的访问协议是HTTPS，所以需要做一个SSL上下文处理
        SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                X509Certificate cert = chain[0];
                return "CN=muyan-yootk.com".equalsIgnoreCase(cert.getSubjectDN().getName());
            }
        }).build();
        // 2、创建SSL连接工厂类
        SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create().setSslContext(sslContext).setTlsVersions(TLS.V_1_2).build();
        // 3、创建HttpClient连接管理类
        HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(sslSocketFactory).build();
        // 4、创建Http请求
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
        // 5、设置请求路径
        String requestUrl = "https://muyan-yootk.com/yootk/upload.action";
        // 6、设置上传文件
        File file = new File("F:" + File.separator + "muyan" + File.separator + "muyan_yootk.png"); // 要上传的文件
        // 7、创建一个指定的请求模式，本次为POST模式
        HttpPost httpPost = new HttpPost(requestUrl); // 以POST模式发送HTTP请求
        // 8、如果要是进行表单上传，则一定要提供有一个MIME的声明“multipart/form-data”
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addPart("message", new StringBody("沐言科技：www.yootk.com", ContentType.create("text/plain", Charset.forName("UTF-8"))));
        builder.addPart("photo", new FileBody(file, ContentType.create("image/png"), file.getName()));
        // 9、将请求参数配置到POST请求之中
        httpPost.setEntity(builder.build()); // 所有的提交参数准备就绪
        // 10、进行HTTP请求的发送，请求发送之后一定会存在有响应信息
        CloseableHttpResponse response = httpClient.execute(httpPost); // 发送HTTP请求
        // 11、HTTP响应是分为两个部分：数据部分、头信息
        System.out.println("【获取响应数据】" + EntityUtils.toString(response.getEntity()));
        // 12、获取全部的头信息数据
        Header headers[] = response.getHeaders(); // 全部头信息
        for (Header header : headers) {
            System.out.println("\t|- 【头信息】name = " + header.getName() + "、value = " + header.getValue());
        }
        System.out.println("【HTTP状态码】" + response.getCode());
    }
}
